package org.mentalsmash.tazio.transactions.model;

import java.util.Iterator;

import org.mentalsmash.tazio.transactions.model.identifiers.OID;

/**
 * The <tt>RootSet</tt> interface represents the contract between the
 * implementation of a Container for {@link TransactionalObject}s and the
 * clients of that container.
 * <p>
 * Each RM and WRM participating to the share has an unique instance of the
 * RootSet. Each instance is a replicated copy of the other. The root set is
 * treated like any other object in the system, and implements itself the
 * {@link TransactionalObject} interface.
 * </p>
 * <p>
 * Unlike <i>"traditional"</i> <tt>TransactionalObject</tt>s it has a predefined
 * identifier as specified in {@link #ROOT_SET_OID}
 * </p>
 */
public interface RootSet extends TransactionalSet {
    final static OID ROOT_SET_OID = OID.ROOT_SET_OID;

    /**
     * Removes an object from the RootSet. If the object is not in the RootSet,
     * it does nothing.
     * <p>
     * The operation is performed outside the context of any possibly running
     * transaction. And it is not transactional itself
     * </p>
     * 
     * @param toRemove
     *            the {@link OID} of the object to remove
     * @return the {@link OID} of the object removed, or <code>null</code> if
     *         nothing was done
     */
    OID doRemoveObject(OID toRemove);

    /**
     * Adds an object to the root set. If another object having the same
     * {@link OID} as <code>obj</cod> is already
     * in the RootSet, that object doesn't get overwritten.
     * <p>
     * The operation is performed outside the context of any possibly running
     * transaction. And it is not transactional itself
     * </p>
     * 
     * @param obj
     *            the instance to add to the RootSet
     */
    void doAddObject(TransactionalObject obj);

    /**
     * Returns an iterator over the {@link TransactionalObject}s in the RootSet.
     * <p>
     * The obtained iterator runs outside the scope of any running transaction,
     * and operations performed through this iterator instance are not
     * transactional themselves
     * </p>
     * 
     * @return an iterator over the objects in the RootSet
     */
    Iterator<TransactionalObject> txIterator();

    /**
     * Retrieves an object from the <tt>RootSet</tt> given its {@link OID}.
     * <p>
     * The operation is performed outside the context of any possibly running
     * transaction. And it is not transactional itself
     * </p>
     * 
     * @param objectId
     *            the identifier of the object to retrieve
     * @return the instance of the transactional object having OID
     *         <code>objectId</code> or null if no such an object is in the
     *         <tt>RootSet</tt>
     */
    TransactionalObject getObject(OID objectId);

    /**
     * Checks whether the <tt>RootSet</tt> contains an object having the provided
     * {@link OID} or not.
     * <p>
     * The operation is performed outside the context of any possibly running
     * transaction. And it is not transactional itself
     * </p>
     * 
     * @param objectId the {@link OID} of the object whose presence is to be checked
     * @return true iff the <tt>RootSet</tt> contains the object.
     */
    boolean containsObject(OID objectId);

}
